package it.cums.views;

import it.cums.base.Activator;
import it.cums.controller.ApplicationController;
import it.cums.editors.SupplierEditor;
import it.cums.editors.SupplierEditorInput;
import it.cums.model.Supplier;
import it.cums.model.Suppliers;
import it.cums.util.MessageCreator;
import it.cums.util.SupplierManager;
import it.cums.wizards.SupplierWizard;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

public class SuppliersView extends ViewPart {
	public static final String ID = "CuMS.SuppliersView";

	private Suppliers suppliers;
	private ApplicationController appController = ApplicationController.getInstance();
	private TableViewer viewer;
	private Action deleteAction;
	private Action createAction;
	private Action doubleClickAction;

	/*
	 * The content provider class is responsible for
	 * providing objects to the view. It can wrap
	 * existing objects in adapters or simply return
	 * objects as-is. These objects may be sensitive
	 * to the current input of the view, or ignore
	 * it and always show the same content 
	 * (like Task List, for example).
	 */
	 
	class ViewContentProvider implements IStructuredContentProvider, PropertyChangeListener {
		
		public ViewContentProvider() {
			suppliers = appController.getSuppliers();
			suppliers.addChangeListener(this);
		}
		
		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
		}
		
		public void dispose() {
		}
		
		public Object[] getElements(Object parent) {
			return suppliers.getSuppliers().toArray();
		}

		@Override
		public void propertyChange(PropertyChangeEvent evt) {
			viewer.refresh();
		}
	}
	
	class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
		public String getColumnText(Object obj, int index) {
			return obj.toString();
		}
		
		public Image getColumnImage(Object obj, int index) {
			return getImage(obj);
		}
		
		public Image getImage(Object obj) {
			return Activator.getImageDescriptor("icons/person.gif").createImage();
		}
	}
	
	class NameSorter extends ViewerSorter {
		
		public int compare(Viewer viewer, Object e1, Object e2) {
			// TODO Auto-generated method stub
			return e1.toString().compareTo(e2.toString());
		}
	}

	/**
	 * The constructor.
	 */
	public SuppliersView() {
	}

	/**
	 * This is a callback that will allow us
	 * to create the viewer and initialize it.
	 */
	public void createPartControl(Composite parent) {
		viewer = new TableViewer(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
		viewer.setContentProvider(new ViewContentProvider());
		viewer.setLabelProvider(new ViewLabelProvider());
		viewer.setSorter(new NameSorter());
		viewer.setInput(getViewSite());
		makeActions();
		hookContextMenu();
		hookDoubleClickAction();
		contributeToActionBars();
		getSite().setSelectionProvider(viewer);
		viewer.addSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				ISelection selection = viewer.getSelection();
				Object obj = ((IStructuredSelection)selection).getFirstElement();
				if (obj instanceof Supplier) {
					deleteAction.setEnabled(true);
				} else {
					deleteAction.setEnabled(false);
				}
			}});
	}

	private void hookContextMenu() {
		MenuManager menuMgr = new MenuManager("#PopupMenu");
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			public void menuAboutToShow(IMenuManager manager) {
				SuppliersView.this.fillContextMenu(manager);
			}
		});
		Menu menu = menuMgr.createContextMenu(viewer.getControl());
		viewer.getControl().setMenu(menu);
		getSite().registerContextMenu(menuMgr, viewer);
	}

	private void contributeToActionBars() {
		IActionBars bars = getViewSite().getActionBars();
		fillLocalPullDown(bars.getMenuManager());
		fillLocalToolBar(bars.getToolBarManager());
	}

	private void fillLocalPullDown(IMenuManager manager) {
		manager.add(deleteAction);
		manager.add(new Separator());
		manager.add(createAction);
	}

	private void fillContextMenu(IMenuManager manager) {
		manager.add(deleteAction);
		manager.add(createAction);
		// Other plug-ins can contribute there actions here
		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
	}
	
	private void fillLocalToolBar(IToolBarManager manager) {
		manager.add(deleteAction);
		manager.add(createAction);
	}

	private void makeActions() {
		deleteAction = new Action() {
			public void run() {
				ISelection selection = viewer.getSelection();
				Object obj = ((IStructuredSelection)selection).getFirstElement();
				Supplier s = (Supplier)obj;
				if (MessageCreator.showConfirmMessage("Are you sure you want to delete supplier '" + s.getName() + "'?")) {
					SupplierManager.getInstance().deleteSupplier(suppliers, s);
				}
			}
		};
		deleteAction.setText("Delete");
		deleteAction.setToolTipText("Delete selected supplier");
		deleteAction.setImageDescriptor(Activator.getImageDescriptor("icons/remove.gif"));
		deleteAction.setEnabled(false);
		createAction = new Action() {
			public void run() {
				SupplierWizard wizard = new SupplierWizard();
				WizardDialog dialog = new WizardDialog(viewer.getTable().getShell(), wizard);
				dialog.open();
			}
		};
		createAction.setText("Create supplier");
		createAction.setToolTipText("Create a new supplier");
		createAction.setImageDescriptor(Activator.getImageDescriptor("icons/person-new.gif"));
		doubleClickAction = new Action() {
			public void run() {
				ISelection selection = viewer.getSelection();
				Object obj = ((IStructuredSelection)selection).getFirstElement();
				Supplier s = (Supplier)obj;
				SupplierEditorInput input = new SupplierEditorInput(s);
				IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
				try {
					page.openEditor(input, SupplierEditor.ID);
					// notify any listeners of the view with the actual data of
					// the view
					viewer.setSelection(viewer.getSelection());
				} catch (PartInitException e) {
					System.out.println(e.getMessage());
				}
			}
		};
	}

	private void hookDoubleClickAction() {
		viewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				doubleClickAction.run();
			}
		});
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		viewer.getControl().setFocus();
	}
}